package com.autumn.xa.a.tuling.jvm;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;

// 打破双亲委派模型
public class MyClassLoaderBroker extends ClassLoader{


    private String classPath;

    public MyClassLoaderBroker(String classPath) {
        this.classPath = classPath;
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        // 打破双亲委派
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);

            if (c == null) {
                // If still not found, then invoke findClass in order
                // to find the class.
                long t1 = System.nanoTime();
                if (!name.contains("JAVAPClass")) {
                    c = this.getParent().loadClass(name);
                } else {
                    c = findClass(name);
                }

                // this is the defining class loader; record the stats
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }

            return c;
        }
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        byte[] data = getData(name);

        name = "com.autumn.xa.a.tuling.jvm.JAVAPClass";

        Class<?> aClass = defineClass(name, data, 0, data.length);

        return aClass;
    }

    byte[] getData(String name) {
        try {
//            name = name.replaceAll("\\.","/");
            FileInputStream in = new FileInputStream(classPath + "/" + name);
            int len = in.available();
            byte[] data1 = new byte[len];
            in.read(data1);
            in.close();
            return data1;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) throws Exception {
        MyClassLoaderBroker classLoader = new MyClassLoaderBroker("D:/temp");

        Class clazz = classLoader.loadClass("JAVAPClass.class");
        Object obj = clazz.newInstance();
        Method method = clazz.getDeclaredMethod("compute", null);
        Object result = method.invoke(obj, null);
        System.out.println(clazz.getClassLoader().getClass().getName());
        System.out.println(result.toString());
    }




}
